//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.tzbank.poc.util;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import com.tzbank.poc.util.Debug;
import com.tzbank.poc.util.IsEmpty;
import org.springframework.core.convert.ConversionException;
import org.w3c.dom.Node;

public class ObjectType {
    public static final String module = ObjectType.class.getName();
    public static final Object NULL = new ObjectType.NullObject();
    public static final String LANG_PACKAGE = "java.lang.";
    public static final String SQL_PACKAGE = "java.sql.";
    private static final Map<String, String> classAlias = new HashMap();
    private static final Map<String, Class<?>> primitives = new HashMap();

    public ObjectType() {
    }

    public static Class<?> loadClass(String className) throws ClassNotFoundException {
        return loadClass(className, (ClassLoader)null);
    }

    public static Class<?> loadClass(String className, ClassLoader loader) throws ClassNotFoundException {
        Class<?> theClass = null;
        if (primitives.containsKey(className)) {
            return (Class)primitives.get(className);
        } else {
            int genericsStart = className.indexOf("<");
            if (genericsStart != -1) {
                className = className.substring(0, genericsStart);
            }

            if (className.endsWith("[]")) {
                if (Character.isLowerCase(className.charAt(0)) && className.indexOf(".") < 0) {
                    String prefix = className.substring(0, 1).toUpperCase();
                    if (className.startsWith("long")) {
                        prefix = "J";
                    } else if (className.startsWith("boolean")) {
                        prefix = "Z";
                    }

                    className = "[" + prefix;
                } else {
                    Class<?> arrayClass = loadClass(className.replace("[]", ""), loader);
                    className = "[L" + arrayClass.getName().replace("[]", "") + ";";
                }
            }

            if (classAlias.containsKey(className)) {
                className = (String)classAlias.get(className);
            }

            if (loader == null) {
                loader = Thread.currentThread().getContextClassLoader();
            }

            theClass = Class.forName(className, true, loader);
            return theClass;
        }
    }

    public static Object getInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> c = loadClass(className);
        Object o = c.newInstance();
        if (Debug.verboseOn()) {
            Debug.logVerbose("Instantiated object: " + o.toString(), module);
        }

        return o;
    }

    public static boolean interfaceOf(Class<?> objectClass, String interfaceName) throws ClassNotFoundException {
        Class<?> interfaceClass = loadClass(interfaceName);
        return interfaceOf(objectClass, interfaceClass);
    }

    public static boolean interfaceOf(Class<?> objectClass, Object interfaceObject) {
        Class<?> interfaceClass = interfaceObject.getClass();
        return interfaceOf(objectClass, interfaceClass);
    }

    public static Object getInstance(String className, Object[] parameters) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?>[] sig = new Class[parameters.length];

        for(int i = 0; i < sig.length; ++i) {
            sig[i] = parameters[i].getClass();
        }

        Class<?> c = loadClass(className);
        Constructor<?> con = c.getConstructor(sig);
        Object o = con.newInstance(parameters);
        if (Debug.verboseOn()) {
            Debug.logVerbose("Instantiated object: " + o.toString(), module);
        }

        return o;
    }

    public static boolean interfaceOf(Object obj, String interfaceName) throws ClassNotFoundException {
        Class<?> interfaceClass = loadClass(interfaceName);
        return interfaceOf(obj, interfaceClass);
    }

    public static boolean interfaceOf(Object obj, Object interfaceObject) {
        Class<?> interfaceClass = interfaceObject.getClass();
        return interfaceOf(obj, interfaceClass);
    }

    public static boolean interfaceOf(Object obj, Class<?> interfaceClass) {
        Class<?> objectClass = obj.getClass();
        return interfaceOf(objectClass, interfaceClass);
    }

    public static boolean interfaceOf(Class<?> objectClass, Class<?> interfaceClass) {
        while(objectClass != null) {
            Class<?>[] ifaces = objectClass.getInterfaces();
            Class[] var3 = ifaces;
            int var4 = ifaces.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                Class<?> iface = var3[var5];
                if (iface == interfaceClass) {
                    return true;
                }
            }

            objectClass = objectClass.getSuperclass();
        }

        return false;
    }

    public static boolean isOrSubOf(Class<?> objectClass, String parentName) throws ClassNotFoundException {
        Class<?> parentClass = loadClass(parentName);
        return isOrSubOf(objectClass, parentClass);
    }

    public static boolean isOrSubOf(Class<?> objectClass, Object parentObject) {
        Class<?> parentClass = parentObject.getClass();
        return isOrSubOf(objectClass, parentClass);
    }

    public static boolean isOrSubOf(Object obj, String parentName) throws ClassNotFoundException {
        Class<?> parentClass = loadClass(parentName);
        return isOrSubOf(obj, parentClass);
    }

    public static boolean isOrSubOf(Object obj, Object parentObject) {
        Class<?> parentClass = parentObject.getClass();
        return isOrSubOf(obj, parentClass);
    }

    public static boolean isOrSubOf(Object obj, Class<?> parentClass) {
        Class<?> objectClass = obj.getClass();
        return isOrSubOf(objectClass, parentClass);
    }

    public static boolean isOrSubOf(Class<?> objectClass, Class<?> parentClass) {
        while(objectClass != null) {
            if (objectClass == parentClass) {
                return true;
            }

            objectClass = objectClass.getSuperclass();
        }

        return false;
    }

    public static boolean instanceOf(Class<?> objectClass, Object typeObject) {
        Class<?> typeClass = typeObject.getClass();
        return instanceOf(objectClass, typeClass);
    }

    public static boolean instanceOf(Class<?> objectClass, String typeName) {
        return instanceOf((Class)objectClass, typeName, (ClassLoader)null);
    }

    public static boolean instanceOf(Object obj, Object typeObject) {
        Class<?> typeClass = typeObject.getClass();
        return instanceOf(obj, typeClass);
    }

    public static boolean instanceOf(Object obj, String typeName) {
        return instanceOf((Object)obj, typeName, (ClassLoader)null);
    }

    public static boolean instanceOf(Class<?> objectClass, String typeName, ClassLoader loader) {
        Class<?> infoClass = loadInfoClass(typeName, loader);
        if (infoClass == null) {
            throw new IllegalArgumentException("Illegal type found in info map (could not load class for specified type)");
        } else {
            return instanceOf(objectClass, infoClass);
        }
    }

    public static boolean instanceOf(Object obj, String typeName, ClassLoader loader) {
        Class<?> infoClass = loadInfoClass(typeName, loader);
        if (infoClass == null) {
            throw new IllegalArgumentException("Illegal type found in info map (could not load class for specified type)");
        } else {
            return instanceOf(obj, infoClass);
        }
    }

    public static Class<?> loadInfoClass(String typeName, ClassLoader loader) {
        try {
            return loadClass(typeName, loader);
        } catch (SecurityException var9) {
            throw new IllegalArgumentException("Problems with classloader: security exception (" + var9.getMessage() + ")");
        } catch (ClassNotFoundException var10) {
            try {
                return loadClass("java.lang." + typeName, loader);
            } catch (SecurityException var7) {
                throw new IllegalArgumentException("Problems with classloader: security exception (" + var7.getMessage() + ")");
            } catch (ClassNotFoundException var8) {
                try {
                    return loadClass("java.sql." + typeName, loader);
                } catch (SecurityException var5) {
                    throw new IllegalArgumentException("Problems with classloader: security exception (" + var5.getMessage() + ")");
                } catch (ClassNotFoundException var6) {
                    throw new IllegalArgumentException("Cannot find and load the class of type: " + typeName + " or of type: " + "java.lang." + typeName + " or of type: " + "java.sql." + typeName + ":  (" + var6.getMessage() + ")");
                }
            }
        }
    }

    public static boolean instanceOf(Object obj, Class<?> typeClass) {
        if (obj == null) {
            return true;
        } else {
            Class<?> objectClass = obj.getClass();
            return instanceOf(objectClass, typeClass);
        }
    }

    public static boolean instanceOf(Class<?> objectClass, Class<?> typeClass) {
        return typeClass.isInterface() && !objectClass.isInterface() ? interfaceOf(objectClass, typeClass) : isOrSubOf(objectClass, typeClass);
    }

//    public static Object simpleTypeConvert(Object obj, String type, String format, Locale locale, boolean noTypeFail) throws Exception {
//        return simpleTypeConvert(obj, type, format, (TimeZone)null, locale, noTypeFail);
//    }

//    public static Object simpleTypeConvert(Object obj, String type, String format, TimeZone timeZone, Locale locale, boolean noTypeFail) throws Exception {
//        if (obj != null && !ValidateUtil.isEmpty(type) && !"Object".equals(type) && !"java.lang.Object".equals(type)) {
//            if ("PlainString".equals(type)) {
//                return obj.toString();
//            } else if (obj instanceof Node) {
//                Node node = (Node)obj;
//                String nodeValue = node.getTextContent();
//                return !"String".equals(type) && !"java.lang.String".equals(type) ? simpleTypeConvert(nodeValue, type, format, timeZone, locale, noTypeFail) : nodeValue;
//            } else {
//                int genericsStart = type.indexOf("<");
//                if (genericsStart != -1) {
//                    type = type.substring(0, genericsStart);
//                }
//
//                Class<?> sourceClass = obj.getClass();
//                Class targetClass = null;
//
//                try {
//                    targetClass = loadClass(type);
//                } catch (ClassNotFoundException var15) {
//                    throw new Exception("Conversion from " + sourceClass.getName() + " to " + type + " not currently supported", var15);
//                }
//
//                if (sourceClass.equals(targetClass)) {
//                    return obj;
//                } else if (obj instanceof String && ((String)obj).length() == 0) {
//                    return null;
//                } else {
//                    Converter converter = null;
//
//                    try {
//                        converter = Converters.getConverter(sourceClass, targetClass);
//                    } catch (ClassNotFoundException var14) {
//                        ;
//                    }
//
//                    if (converter != null) {
//                        if (converter instanceof LocalizedConverter) {
//                            LocalizedConverter<Object, Object> localizedConverter = (LocalizedConverter)converter;
//                            if (timeZone == null) {
//                                timeZone = TimeZone.getDefault();
//                            }
//
//                            if (locale == null) {
//                                locale = Locale.getDefault();
//                            }
//
//                            try {
//                                return localizedConverter.convert(obj, locale, timeZone, format);
//                            } catch (ConversionException var12) {
//                                Debug.logWarning(var12, "Exception thrown while converting type: ", module);
//                                throw new Exception(var12.getMessage(), var12);
//                            }
//                        } else {
//                            try {
//                                return converter.convert(obj);
//                            } catch (ConversionException var13) {
//                                Debug.logWarning(var13, "Exception thrown while converting type: ", module);
//                                throw new Exception(var13.getMessage(), var13);
//                            }
//                        }
//                    } else if (targetClass.equals(String.class)) {
//                        Debug.logWarning("No special conversion available for " + obj.getClass().getName() + " to String, returning object.toString().", module);
//                        return obj.toString();
//                    } else if (noTypeFail) {
//                        throw new Exception("Conversion from " + obj.getClass().getName() + " to " + type + " not currently supported");
//                    } else {
//                        if (Debug.infoOn()) {
//                            Debug.logInfo("No type conversion available for " + obj.getClass().getName() + " to " + targetClass.getName() + ", returning original object.", module);
//                        }
//
//                        return obj;
//                    }
//                }
//            }
//        } else {
//            return obj;
//        }
//    }

//    public static Object simpleTypeConvert(Object obj, String type, String format, Locale locale) throws Exception {
//        return simpleTypeConvert(obj, type, format, locale, true);
//    }

//    public static Boolean doRealCompare(Object value1, Object value2, String operator, String type, String format, List<Object> messages, Locale locale, ClassLoader loader, boolean value2InlineConstant) {
//        boolean verboseOn = Debug.verboseOn();
//        if (verboseOn) {
//            Debug.logVerbose("Comparing value1: \"" + value1 + "\" " + operator + " value2:\"" + value2 + "\"", module);
//        }
//
//        try {
//            if (!"PlainString".equals(type)) {
//                Class<?> clz = loadClass(type, loader);
//                type = clz.getName();
//            }
//        } catch (ClassNotFoundException var20) {
//            Debug.logWarning("The specified type [" + type + "] is not a valid class or a known special type, may see more errors later because of this: " + var20.getMessage(), module);
//        }
//
//        if (value1 == null) {
//            if ("is-null".equals(operator)) {
//                return Boolean.TRUE;
//            }
//
//            if ("is-not-null".equals(operator)) {
//                return Boolean.FALSE;
//            }
//
//            if ("is-empty".equals(operator)) {
//                return Boolean.TRUE;
//            }
//
//            if ("is-not-empty".equals(operator)) {
//                return Boolean.FALSE;
//            }
//
//            if ("contains".equals(operator)) {
//                return Boolean.FALSE;
//            }
//        }
//
//        int result = false;
//        Object convertedValue2 = null;
//        Locale value2Locale;
//        if (value2 != null) {
//            value2Locale = locale;
//            if (value2InlineConstant) {
//                value2Locale = UtilMisc.parseLocale("en");
//            }
//
//            try {
//                convertedValue2 = simpleTypeConvert(value2, type, format, value2Locale);
//            } catch (Exception var19) {
//                Debug.logError(var19, module);
//                messages.add("Could not convert value2 for comparison: " + var19.getMessage());
//                return null;
//            }
//        }
//
//        if ("contains".equals(operator) && value1 instanceof Collection) {
//            Collection<?> col1 = (Collection)value1;
//            return col1.contains(convertedValue2) ? Boolean.TRUE : Boolean.FALSE;
//        } else {
//            value2Locale = null;
//
//            Object convertedValue1;
//            try {
//                convertedValue1 = simpleTypeConvert(value1, type, format, locale);
//            } catch (Exception var18) {
//                Debug.logError(var18, module);
//                messages.add("Could not convert value1 for comparison: " + var18.getMessage());
//                return null;
//            }
//
//            if (convertedValue1 == null || convertedValue2 == null) {
//                if ("equals".equals(operator)) {
//                    return convertedValue1 == null && convertedValue2 == null ? Boolean.TRUE : Boolean.FALSE;
//                }
//
//                if ("not-equals".equals(operator)) {
//                    return convertedValue1 == null && convertedValue2 == null ? Boolean.FALSE : Boolean.TRUE;
//                }
//
//                if (!"is-not-empty".equals(operator) && !"is-empty".equals(operator)) {
//                    if (convertedValue1 == null) {
//                        messages.add("Left value is null, cannot complete compare for the operator " + operator);
//                        return null;
//                    }
//
//                    if (convertedValue2 == null) {
//                        messages.add("Right value is null, cannot complete compare for the operator " + operator);
//                        return null;
//                    }
//                }
//            }
//
//            String str1;
//            String str2;
//            if ("contains".equals(operator)) {
//                if (!"java.lang.String".equals(type) && !"PlainString".equals(type)) {
//                    messages.add("Error in XML file: cannot do a contains compare between a String and a non-String type");
//                    return null;
//                } else {
//                    str1 = (String)convertedValue1;
//                    str2 = (String)convertedValue2;
//                    return str1.indexOf(str2) < 0 ? Boolean.FALSE : Boolean.TRUE;
//                }
//            } else if ("is-empty".equals(operator)) {
//                if (convertedValue1 == null) {
//                    return Boolean.TRUE;
//                } else if (convertedValue1 instanceof String && ((String)convertedValue1).length() == 0) {
//                    return Boolean.TRUE;
//                } else if (convertedValue1 instanceof List && ((List)convertedValue1).size() == 0) {
//                    return Boolean.TRUE;
//                } else {
//                    return convertedValue1 instanceof Map && ((Map)convertedValue1).size() == 0 ? Boolean.TRUE : Boolean.FALSE;
//                }
//            } else if ("is-not-empty".equals(operator)) {
//                if (convertedValue1 == null) {
//                    return Boolean.FALSE;
//                } else if (convertedValue1 instanceof String && ((String)convertedValue1).length() == 0) {
//                    return Boolean.FALSE;
//                } else if (convertedValue1 instanceof List && ((List)convertedValue1).size() == 0) {
//                    return Boolean.FALSE;
//                } else {
//                    return convertedValue1 instanceof Map && ((Map)convertedValue1).size() == 0 ? Boolean.FALSE : Boolean.TRUE;
//                }
//            } else {
//                int result;
//                if (!"java.lang.String".equals(type) && !"PlainString".equals(type)) {
//                    if (!"java.lang.Double".equals(type) && !"java.lang.Float".equals(type) && !"java.lang.Long".equals(type) && !"java.lang.Integer".equals(type) && !"java.math.BigDecimal".equals(type)) {
//                        if ("java.sql.Date".equals(type)) {
//                            Date value1Date = (Date)convertedValue1;
//                            Date value2Date = (Date)convertedValue2;
//                            result = value1Date.compareTo(value2Date);
//                        } else if ("java.sql.Time".equals(type)) {
//                            Time value1Time = (Time)convertedValue1;
//                            Time value2Time = (Time)convertedValue2;
//                            result = value1Time.compareTo(value2Time);
//                        } else if ("java.sql.Timestamp".equals(type)) {
//                            Timestamp value1Timestamp = (Timestamp)convertedValue1;
//                            Timestamp value2Timestamp = (Timestamp)convertedValue2;
//                            result = value1Timestamp.compareTo(value2Timestamp);
//                        } else if ("java.lang.Boolean".equals(type)) {
//                            Boolean value1Boolean = (Boolean)convertedValue1;
//                            Boolean value2Boolean = (Boolean)convertedValue2;
//                            if ("equals".equals(operator)) {
//                                if ((!value1Boolean || !value2Boolean) && (value1Boolean || value2Boolean)) {
//                                    result = 1;
//                                } else {
//                                    result = 0;
//                                }
//                            } else {
//                                if (!"not-equals".equals(operator)) {
//                                    messages.add("Can only compare Booleans using the operators 'equals' or 'not-equals'");
//                                    return null;
//                                }
//
//                                if ((value1Boolean || !value2Boolean) && (!value1Boolean || value2Boolean)) {
//                                    result = 1;
//                                } else {
//                                    result = 0;
//                                }
//                            }
//                        } else {
//                            if (!"java.lang.Object".equals(type)) {
//                                messages.add("Type \"" + type + "\" specified for compare not supported.");
//                                return null;
//                            }
//
//                            if (convertedValue1.equals(convertedValue2)) {
//                                result = 0;
//                            } else {
//                                result = 1;
//                            }
//                        }
//                    } else {
//                        Number tempNum = (Number)convertedValue1;
//                        double value1Double = tempNum.doubleValue();
//                        tempNum = (Number)convertedValue2;
//                        double value2Double = tempNum.doubleValue();
//                        if (value1Double < value2Double) {
//                            result = -1;
//                        } else if (value1Double > value2Double) {
//                            result = 1;
//                        } else {
//                            result = 0;
//                        }
//                    }
//                } else {
//                    str1 = (String)convertedValue1;
//                    str2 = (String)convertedValue2;
//                    if (str1.length() == 0 || str2.length() == 0) {
//                        if ("equals".equals(operator)) {
//                            return str1.length() == 0 && str2.length() == 0 ? Boolean.TRUE : Boolean.FALSE;
//                        } else if (!"not-equals".equals(operator)) {
//                            messages.add("ERROR: Could not do a compare between strings with one empty string for the operator " + operator);
//                            return null;
//                        } else {
//                            return str1.length() == 0 && str2.length() == 0 ? Boolean.FALSE : Boolean.TRUE;
//                        }
//                    }
//
//                    result = str1.compareTo(str2);
//                }
//
//                if (verboseOn) {
//                    Debug.logVerbose("Got Compare result: " + result + ", operator: " + operator, module);
//                }
//
//                if ("less".equals(operator)) {
//                    if (result >= 0) {
//                        return Boolean.FALSE;
//                    }
//                } else if ("greater".equals(operator)) {
//                    if (result <= 0) {
//                        return Boolean.FALSE;
//                    }
//                } else if ("less-equals".equals(operator)) {
//                    if (result > 0) {
//                        return Boolean.FALSE;
//                    }
//                } else if ("greater-equals".equals(operator)) {
//                    if (result < 0) {
//                        return Boolean.FALSE;
//                    }
//                } else if ("equals".equals(operator)) {
//                    if (result != 0) {
//                        return Boolean.FALSE;
//                    }
//                } else {
//                    if (!"not-equals".equals(operator)) {
//                        messages.add("Specified compare operator \"" + operator + "\" not known.");
//                        return null;
//                    }
//
//                    if (result == 0) {
//                        return Boolean.FALSE;
//                    }
//                }
//
//                if (verboseOn) {
//                    Debug.logVerbose("Returning true", module);
//                }
//
//                return Boolean.TRUE;
//            }
//        }
//    }

    public static boolean isEmpty(Object value) {
        if (value == null) {
            return true;
        } else if (value instanceof String) {
            return ((String)value).length() == 0;
        } else if (value instanceof Collection) {
            return ((Collection)value).size() == 0;
        } else if (value instanceof Map) {
            return ((Map)value).size() == 0;
        } else if (value instanceof CharSequence) {
            return ((CharSequence)value).length() == 0;
        } else if (value instanceof IsEmpty) {
            return ((IsEmpty)value).isEmpty();
        } else if (value instanceof Boolean) {
            return false;
        } else if (value instanceof Number) {
            return false;
        } else if (value instanceof Character) {
            return false;
        } else if (value instanceof java.util.Date) {
            return false;
        } else {
            if (Debug.verboseOn()) {
                Debug.logVerbose("In ObjectType.isEmpty(Object value) returning false for " + value.getClass() + " Object.", module);
            }

            return false;
        }
    }

    static {
        classAlias.put("Object", "java.lang.Object");
        classAlias.put("String", "java.lang.String");
        classAlias.put("Boolean", "java.lang.Boolean");
        classAlias.put("BigDecimal", "java.math.BigDecimal");
        classAlias.put("BigInteger", "java.math.BigInteger");
        classAlias.put("Double", "java.lang.Double");
        classAlias.put("Float", "java.lang.Float");
        classAlias.put("Long", "java.lang.Long");
        classAlias.put("Integer", "java.lang.Integer");
        classAlias.put("Short", "java.lang.Short");
        classAlias.put("Byte", "java.lang.Byte");
        classAlias.put("Character", "java.lang.Character");
        classAlias.put("Timestamp", "java.sql.Timestamp");
        classAlias.put("Time", "java.sql.Time");
        classAlias.put("Date", "java.sql.Date");
        classAlias.put("Locale", "java.util.Locale");
        classAlias.put("Collection", "java.util.Collection");
        classAlias.put("List", "java.util.List");
        classAlias.put("Set", "java.util.Set");
        classAlias.put("Map", "java.util.Map");
        classAlias.put("HashMap", "java.util.HashMap");
        classAlias.put("TimeZone", "java.util.TimeZone");
        classAlias.put("TimeDuration", "com.bosent.base.util.TimeDuration");
        classAlias.put("GenericValue", "com.bosent.entity.GenericValue");
        classAlias.put("GenericPK", "com.bosent.entity.GenericPK");
        classAlias.put("GenericEntity", "com.bosent.entity.GenericEntity");
        primitives.put("boolean", Boolean.TYPE);
        primitives.put("short", Short.TYPE);
        primitives.put("int", Integer.TYPE);
        primitives.put("long", Long.TYPE);
        primitives.put("float", Float.TYPE);
        primitives.put("double", Double.TYPE);
        primitives.put("byte", Byte.TYPE);
        primitives.put("char", Character.TYPE);
    }

    public static final class NullObject implements Serializable {
        public NullObject() {
        }

        @Override
        public String toString() {
            return "ObjectType.NullObject";
        }

        @Override
        public int hashCode() {
            return this.toString().hashCode();
        }

        @Override
        public boolean equals(Object other) {
            return other instanceof ObjectType.NullObject;
        }
    }
}
